<template>
	<view>
		<uni-nav-bar background-color="#fff" color="#000" :status-bar="true" :title="chatTitle" fixed>
			<view slot="left">
				<view class="navWp">
					<view class="back" @click="goBack">
						<u-icon name="arrow-left" color="#000000" size="50"></u-icon>
					</view>
					<view class="user" @click="showUser">
						<u-icon name="account-fill" size="50" color="#333333"></u-icon>
					</view>
				</view>
			</view>
		</uni-nav-bar>
		<!--  -->
		<view class="content" @touchstart="hideDrawer">
			<scroll-view class="msg-list" scroll-y="true" :scroll-with-animation="scrollAnimation"
				:scroll-top="scrollTop" :scroll-into-view="scrollToView" @scrolltoupper="loadHistory"
				upper-threshold="50">
				<!-- 加载历史数据waitingUI -->
				<view class="loading">
					<view class="spinner">
						<view class="rect1"></view>
						<view class="rect2"></view>
						<view class="rect3"></view>
						<view class="rect4"></view>
						<view class="rect5"></view>
					</view>
				</view>
				<view class="row" v-for="(row,index) in msgList" :key="index" :id="'msg'+row.msg.id">
					<!-- 系统消息 -->
					<block v-if="row.type=='system'">
						<view class="system">
							<!-- 文字消息 -->
							<view v-if="row.msg.format==0" class="text">
								{{row.msg.content}}
							</view>
						</view>
					</block>
					<!-- 用户消息 -->
					<block v-if="row.type=='user'">
						<!-- 自己发出的消息 -->
						<view class="my" v-if="row.msg.openId==openId" @longpress.stop="delMsg(row.msg)">
							<!-- 左-消息 -->
							<view class="left mySendTimeWp">
								<!-- 时间 -->
								<view class="mySendTime">
									{{row.msg.time?row.msg.time:''}}
								</view>
								<!-- 文字消息 -->
								<view v-if="row.msg.format==0" class="bubble">
									<rich-text :nodes="row.msg.content"></rich-text>
								</view>
								<!-- 图片消息 -->
								<view v-if="row.msg.format==2" class="bubble img" @tap="showPic(row.msg)">
									<u--image :showLoading="true" :src="row.msg.content" :showMenuByLongpress="false"
										mode="aspectFit"></u--image>
								</view>
							</view>
							<!-- 右-头像 -->
							<view class="right">
								<!-- 本人信息 -->
								<view class="myname">
									<view class="name">我</view>
								</view>
								<image :src="userInfo.head"></image>
							</view>
						</view>
						<!-- 别人发出的消息 -->
						<view class="other" v-if="row.msg.openId!=openId">
							<!-- 左-头像 -->
							<view class="left">
								<image :src="row.msg.headUrl"></image>
							</view>
							<!-- 右-用户名称-时间-消息 -->
							<view class="right">
								<view class="username">
									<view class="name">{{row.msg.nickname}}</view>
									<view class="time">{{row.msg.time}}</view>
								</view>
								<!-- 文字消息 -->
								<view v-if="row.msg.format==0" class="bubble">
									<rich-text :nodes="row.msg.content"></rich-text>
								</view>
								<!-- 图片消息 -->
								<view v-if="row.msg.format==2" class="bubble img" @tap="showPic(row.msg)">
									<u--image :showLoading="true" :src="row.msg.content" :showMenuByLongpress="false"
										mode="aspectFit"></u--image>
								</view>
							</view>
						</view>
					</block>
				</view>
			</scroll-view>
		</view>
		<!-- 抽屉栏 -->
		<view class="popup-layer" :class="popupLayerClass" @touchmove.stop.prevent="discard">
			<!-- 更多功能 相册-拍照- -->
			<view class="more-layer" :class="{hidden:hideMore}">
				<view class="list">
					<view class="box" @tap="chooseImage">
						<view class="icon tupian2"></view>
					</view>
					<view class="box" @tap="camera">
						<view class="icon paizhao"></view>
					</view>
				</view>
			</view>
		</view>
		<!-- 底部输入栏 -->
		<view class="input-box" :class="popupLayerClass" @touchmove.stop.prevent="discard">
			<view class="more" @tap="showMore">
				<view class="icon add"></view>
			</view>
			<view class="textbox">
				<view class="text-mode">
					<view class="box">
						<textarea auto-height="true" v-model="textMsg" @focus="textareaFocus" confirmType="send"
							:show-confirm-bar="false" :cursor-spacing="20" />
					</view>
				</view>
			</view>
			<view class="send" @tap="sendText">
				<view class="btn">发送</view>
			</view>
		</view>
		<u-safe-bottom></u-safe-bottom>
		<!-- 人员列表弹窗 -->
		<u-popup :show="showList" @close="closeShowList" mode="bottom" :closeOnClickOverlay='true' :round="30"
			closeable>
			<view class="personListWp">
				<view class="personItem" v-for="(item,index) in personList">
					<view class="personHead">
						<img :src="item.chatHead" alt="">
					</view>
					<view class="personName" :class="item.onLine==1?'':'isOffline' ">
						{{item.senderName}} <text
							style="color:#ccc;margin-left: 10rpx;font-size: 20rpx;">{{item.onLine==1?'':'已离线'}}</text>
					</view>
				</view>
			</view>
		</u-popup>
	</view>
</template>
<script>
	var socket = null;
	import webSocketClass from '@/config/websocketClass.js'
	import baseConfig from '@/config/baseUrl.js';
	import {
		mapState
	} from 'vuex'
	export default {

		data() {
			return {
				webSocketObj: undefined,
				roomId: '',
				roomNo: '',
				//文字消息
				textMsg: '',
				//消息列表
				isHistoryLoading: false,
				scrollAnimation: false,
				scrollTop: 0,
				scrollToView: '',
				msgList: [{
					type: "system",
					msg: {
						id: 0,
						format: 0,
						content: "欢迎进入组局聊天室"
					}
				}, ],
				msgImgList: [],
				openId: '',
				// 抽屉参数
				popupLayerClass: '',
				// more参数
				hideMore: true,
				//红包相关参数
				windowsState: '',
				showList: false,
				headBeatTime: undefined,
				isconnect: false,
				pageNo: 1,
				chatTotal: null,
				chatTitle: '',
				personList: []
			};
		},
		created() {
			let data = uni.getStorageSync('openId')
			if (data.openid) {
				this.openId = data.openid
			}
		},
		computed: {
			...mapState(['userInfo']),
		},
		onLoad(option) {
			console.log(option, 'chatroom');
			const {
				roomId,
				roomNo,
				chatTitle
			} = option
			this.roomId = roomId
			this.roomNo = roomNo
			this.chatTitle = chatTitle
			this.webSocketObj = new webSocketClass(`${baseConfig.webSocketUrl}/websockets/${this.openId}/${this.roomId}`,
				50)
			if (this.webSocketObj) {
				// 如果sockt实例未连接
				if (!this.webSocketObj.isConnect) {
					this.webSocketObj.initSocket()
				}
			} else {
				// 如果没有sockt实例，则创建
				this.webSocketObj.initSocket()
			}
			this.quertChatRoomInfo() //查询聊天室人员
			//监听服务器发送信息
			uni.$on('message', this.getMessage)
			this.getLastHistory()
		},
		onShow() {
			this.scrollTop = 9999999;

		},
		// 页面卸载时取消监听
		onUnload() {
			this.webSocketObj.closeSocket()
			uni.$off('message', this.getMessage)
		},
		methods: {
			//查询聊天室人员
			async quertChatRoomInfo() {
				let payload = {
					openId: this.openId,
					roomId: this.roomId
				}
				let res = await this.$api.goOnline(payload)
				if (res.success && res.result.length > 0) {
					this.personList = res.result
					console.log(this.personList, '查询聊天室人员');
				} else {
					this.personList = []
				}

			},
			// 发送文字消息
			async sendText() {
				this.hideDrawer(); //隐藏抽屉
				if (!this.textMsg) {
					return;
				}
				var nowDate = new Date();
				let payload = {
					roomId: this.roomId,
					openId: this.userInfo.openId,
					headUrl: this.userInfo.head,
					nickname: this.userInfo.name,
					format: 0,
					content: this.textMsg,
				}
				let res = await this.$api.sendMessage(payload)
				if (res.success) {
					this.textMsg = ''; //清空输入框
				} else {
					uni.showToast({
						title: res.message,
						icon: 'none'
					});
				}
			},
			// 点击导航栏左侧
			goBack() {
				uni.navigateBack()
			},
			//撤回信息
			async delMsg(item) {
				console.log(item, '撤回信息');
				//二次确认 
				uni.showModal({
					title: '提示',
					content: '是否撤回信息',
					success: async (res) => {
						if (res.confirm) {
							let res = await this.$api.revokeMessage(item.id)
							if (res.success) {
								let delIndex = this.msgList.findIndex(msgListItem => {
									return msgListItem.msg.id == item.id
								})
								console.log(this.msgList);
								console.log('撤回成功', delIndex);
								if (delIndex !== -1) {
									this.msgList.splice(delIndex, 1)
								}
							}
						} else if (res.cancel) {
							console.log('用户点击取消');
						}
					}
				});

			},
			showUser() {
				console.log('显示用户列表');
				this.showList = !this.showList
			},
			closeShowList() {
				this.showList = false
			},
			getMessage(msg) {
				let data = JSON.parse(msg.data)
				console.log(data.data, '服务器返回信息');
				if (data.code == 100) {
					// console.log('服务器返回心跳', data);
					return
				}
				if (data.code == 102) {
					console.log(data.data, '撤回信息Id');
					let delIndex = this.msgList.findIndex(msgListItem => {
						return msgListItem.msg.id == data.data
					})
					if (delIndex !== -1) {
						this.msgList.splice(delIndex, 1)
						console.log('撤回成功,删除delIndex', delIndex);
					}
					return
				}
				if (data.code == 101 && data.data.content) {

					let {
						id,
						content,
						format,
						headUrl,
						nickname,
						openId,
						roomId,
						sendTime
					} = data.data
					format = Number(format)
					let msgFormat = {
						type: 'user',
						msg: {
							id,
							time: sendTime,
							format,
							openId,
							nickname,
							headUrl,
							content
						}
					}
					this.screenMsg(msgFormat)
				}

			},
			// 接受消息(筛选处理)
			screenMsg(msg) {
				console.log(msg, '接收到的信息');
				if (msg.type == 'system') {
					// 系统消息
					switch (msg.format) {
						case 0:
							this.addSystemTextMsg(msg);
							break;
					}
				} else if (msg.type == 'user') {
					// 用户消息 区分 文本和图片
					switch (msg.msg.format) {
						case 0:
							this.addTextMsg(msg);
							break;
						case 1:
							//todo 添加表情
							console.log('todo 添加表情')
							break;
						case 2:
							console.log('添加图片')
							this.addImgMsg(msg);
							break;
					}
					if (msg.msg.openId != this.openId) {
						console.log('其他人的消息,做提醒');
						// uni.vibrateLong();
					}
				}
				this.$nextTick(function() {
					// 滚动到底
					this.scrollToView = 'msg' + msg.msg.id
				});
			},
			//获取最新一次历史记录
			async getLastHistory() {
				this.scrollAnimation = true; //关闭滑动动画
				let Viewid = this.msgList[0].msg.id; //记住第一个信息ID
				let payload = {
					openId: this.openId,
					pageNo: 1,
					pageSize: 10,
					roomId: this.roomId,
					type: 0 //0-滑动屏幕获取
				}
				let resHistory = await this.$api.queryChatHistory(payload)
				if (resHistory.success) {
					console.log(resHistory.result, '获取聊天记录');
					this.chatTotal = resHistory.result.total
					let list = resHistory.result.records
					list = list.map(item => {
						let newItem = {
							type: 'user',
							msg: {
								id: item.id,
								time: item.sendTime,
								format: item.type,
								openId: item.senderId,
								nickname: item.senderName,
								headUrl: item.chatHead,
								content: item.message,
								isDel: item.isDel,
								isRevoke: item.isRevoke,
								roomId: item.roomId,
								recipientId: item.recipientId
							}
						}
						return newItem
					})
					//过滤 删除和撤回的 item
					list = list.filter(item => {
						return item.isDel != 1 || item.isRevoke != 1
					})
					console.log(list, 'list处理后');
					for (let i = 0; i < list.length; i++) {
						this.msgList.unshift(list[i]);
					}
					console.log(this.msgList, 'this.msgList');
					//这段代码很重要，不然每次加载历史数据都会跳到顶部
					this.$nextTick(function() {
						this.scrollToView = 'msg' + Viewid; //跳转上次的第一行信息位置
						this.$nextTick(function() {
							this.scrollAnimation = true; //恢复滚动动画
						});
					});
					this.isHistoryLoading = false;
				} else {
					this.isHistoryLoading = false;
					uni.showToast({
						title: resHistory.message,
						icon: 'none'
					});
				}
			},


			//触发滑动到顶部(加载历史信息记录)
			async loadHistory(e) {
				if (this.isHistoryLoading) {
					return;
				}

				this.pageNo++
				this.isHistoryLoading = true; //参数作为进入请求标识，防止重复请求
				this.scrollAnimation = false; //关闭滑动动画
				let Viewid = this.msgList[0].msg.id; //记住第一个信息ID
				let payload = {
					openId: this.openId,
					pageNo: this.pageNo,
					pageSize: 10,
					roomId: this.roomId,
					type: 0 //0-滑动屏幕获取
				}

				let resHistory = await this.$api.queryChatHistory(payload)
				if (resHistory.success && resHistory.result.records.length != 0) {
					console.log(resHistory.result, '获取聊天记录');
					this.chatTotal = resHistory.result.total
					// let list = resHistory.result.records.reverse()
					let list = resHistory.result.records
					list = list.map(item => {
						let newItem = {
							type: 'user',
							msg: {
								id: item.id,
								time: item.sendTime,
								format: item.type,
								openId: item.senderId,
								nickname: item.senderName,
								headUrl: item.chatHead,
								content: item.message,
								isDel: item.isDel,
								isRevoke: item.isRevoke,
								roomId: item.roomId,
								recipientId: item.recipientId
							}
						}
						return newItem
					})
					//过滤 删除和撤回的 item
					// list = list.filter(item => {
					// 	return item.msg.isRevoke == 0
					// })
					console.log(list, 'list处理后');
					// this.msgList = []
					for (let i = 0; i < list.length; i++) {
						this.msgList.unshift(list[i]);
					}
					this.msgList = this.msgList.filter(item => {
						return item.msg.isRevoke == 0
					})
					//这段代码很重要，不然每次加载历史数据都会跳到顶部
					this.$nextTick(function() {
						this.scrollToView = 'msg' + Viewid; //跳转上次的第一行信息位置
						this.$nextTick(function() {
							this.scrollAnimation = true; //恢复滚动动画
						});
					});
					this.isHistoryLoading = false;
				} else {
					this.isHistoryLoading = false;
					uni.showToast({
						title: '没有更多数据',
						icon: 'none'
					});
				}

			},
			// 加载初始页面消息
			getMsgList() {
				// 消息列表
				let list = [{
					type: "system",
					msg: {
						id: 0,
						format: 0,
						content: "欢迎进入聊天室"
					}
				}, ]
				this.msgList = list;
				// 滚动到底部
				this.$nextTick(function() {
					//进入页面滚动到底部
					this.scrollTop = 9999;
					this.$nextTick(function() {
						this.scrollAnimation = true;
					});

				});
			},
			//处理图片尺寸，如果不处理宽高，新进入页面加载图片时候会闪
			setPicSize(content) {
				// 让图片最长边等于设置的最大长度，短边等比例缩小，图片控件真实改变，区别于aspectFit方式。
				let maxW = uni.upx2px(350); //350是定义消息图片最大宽度
				let maxH = uni.upx2px(350); //350是定义消息图片最大高度
				if (content.w > maxW || content.h > maxH) {
					let scale = content.w / content.h;
					content.w = scale > 1 ? maxW : maxH * scale;
					content.h = scale > 1 ? maxW / scale : maxH;
				}
				return content;
			},

			//更多功能(点击+弹出) 
			showMore() {
				this.isVoice = false;
				this.hideEmoji = true;
				if (this.hideMore) {
					this.hideMore = false;
					this.openDrawer();
				} else {
					this.hideDrawer();
				}
			},
			// 打开抽屉
			openDrawer() {
				this.popupLayerClass = 'showLayer';
			},
			// 隐藏抽屉
			hideDrawer() {
				this.popupLayerClass = '';
				setTimeout(() => {
					this.hideMore = true;
					this.hideEmoji = true;
				}, 150);
			},
			// 选择图片发送
			chooseImage() {
				this.getImage('album');
			},
			//拍照发送
			camera() {
				this.getImage('camera');
			},
			//获取焦点，如果不是选表情ing,则关闭抽屉
			textareaFocus() {
				if (this.popupLayerClass == 'showLayer' && this.hideMore == false) {
					this.hideDrawer();
				}
			},
			//选照片 or 拍照
			getImage(type) {
				this.hideDrawer();
				uni.chooseImage({
					sourceType: [type],
					sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图，默认二者都有
					success: (res) => {
						for (let i = 0; i < res.tempFilePaths.length; i++) {
							uni.getImageInfo({
								src: res.tempFilePaths[i],
								success: async (image) => {
									const result = await this.uploadFilePromise(res.tempFilePaths[
										i])
									var nowDate = new Date();
									let payload = {
										content: result,
										format: 2,
										nickname: this.userInfo.name,
										headUrl: this.userInfo.head,
										roomId: this.roomId,
										openId: this.userInfo.openId,
									};
									let sendMessage = await this.$api.sendMessage(payload)

									if (sendMessage.success) {
										console.log(sendMessage.result);
									} else {
										uni.showToast({
											title: sendMessage.message,
											icon: 'none'
										});
									}
									// this.screenMsg(msg);
								}
							});
						}
					}
				});
			},

			// 发送消息
			sendMsg(content, type) {
				//实际应用中，此处应该提交长连接，模板仅做本地处理。
				var nowDate = new Date();
				let lastid = this.msgList[this.msgList.length - 1].msg.id;
				lastid++;
				let msg = {
					type: 'user',
					msg: {
						id: lastid,
						time: nowDate.getHours() + ":" + nowDate.getMinutes(),
						type: type,
						userinfo: {
							uid: 0,
							username: "我",
							face: "https://file.casugn.com/storecompcard/temp/avatar1_1654829744499.png"
						},
						content: content
					}
				}
				// 屏幕显示消息
				this.screenMsg(msg);

			},

			// 添加文字消息到列表
			addTextMsg(msg) {
				console.log('添加文字消息到列表', msg);
				this.msgList.push(msg);
			},
			// 添加图片消息到列表
			addImgMsg(msg) {
				console.log('添加图片消息到列表');
				// msg.msg.content = this.setPicSize(msg.msg.content);
				this.msgImgList.push(msg.msg.content);
				this.msgList.push(msg);
			},
			// 添加系统文字消息到列表
			addSystemTextMsg(msg) {
				this.msgList.push(msg);
			},
			sendSystemMsg(content, type) {
				let lastid = this.msgList[this.msgList.length - 1].msg.id;
				lastid++;
				let row = {
					type: "system",
					msg: {
						id: lastid,
						type: type,
						content: content
					}
				};
				this.screenMsg(row)
			},
			// 预览图片
			showPic(msg) {
				let arrShow = []
				arrShow.splice(0, 1, msg.content)
				uni.previewImage({
					current: 0,
					urls: arrShow,
					indicator: "default"
				});
			},
			uploadFilePromise(url) {
				return new Promise((resolve, reject) => {
					let a = uni.uploadFile({
						url: baseConfig.uploadUrl + '/casugn-system/sys/common/upload',
						filePath: url,
						name: 'file',
						success: (res) => {
							let data = JSON.parse(res.data)
							if (data.success) {
								resolve(data.message)
							}
						}
					});
				})
			},
		}
	}
</script>
<style lang="scss">
	@import "@/static/css/style.scss";

	.navWp {
		display: flex;
		align-items: center;

		.back {}

		.user {
			margin-left: 20upx;
		}
	}

	.personListWp {
		max-height: 30vh;
		overflow: auto;
		padding: 30upx;

		.personItem {
			padding: 20upx 0;
			border-bottom: 1upx solid #eee;
			// margin-top:50upx;
			display: flex;
			justify-content: space-between;
			align-items: center;

			.personHead {
				width: 80upx;
				height: 80upx;

				img {
					width: 100%;
					height: 100%;
				}
			}

			.personName {
				margin-left: 30upx;
				flex: 1;
				font-size: 24upx;
				color: #555;
			}

			.isOffline {
				color: red
			}
		}
	}
</style>
